<template>
  <div
    :class="className"
    :style="{ height: height, width: width }"
    v-loading="loading"
  />
</template>

<script>
import resize from "./mixins/resize";
import mixin from "./mixins/mixin";

export default {
  mixins: [resize, mixin],
  props: {
    className: {
      type: String,
      default: "chart",
    },
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "100%",
    },
    autoResize: {
      type: Boolean,
      default: true,
    },
    option: {
      type: Object,
      default: () => {},
      required: true,
    },
    // 点击事件，可以点击的项
    enableClickOptions: {
      type: Array,
      default: () => [],
    },
    // 默认滚动条起始位置
    // 传入坐标的值：{xAxis:'2024-02'}；
    // 传入{xAxis:'currentMonth'}：最后一项是当月；
    // 传入{xAxis:'notEmpty'}：第一项是非空数据
    defaultZoomPosition: {
      type: Object,
      default: null,
    },
    // x轴是否可以选中
    xAxisSelectable: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      chart: null,
      chartOption: null,
      loading: true,
      datazoomDataIndex: 0, //data轮播位置
      xAxisLabelActives: null, //横坐标选中值
    };
  },
  mounted() {
    this.initChart();
  },
  beforeDestroy() {
    if (!this.chart) {
      return;
    }

    this.chart.off("click");

    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      if (!this.$el) {
        return;
      }
      if (!this.chart) {
        this.chart = this.$echarts.init(this.$el);

        this.initEvent();
      }

      this.setOptions();
    },
    initEvent() {
      if (!this.enableClickOptions?.length) {
        return;
      }

      this.chart.off("click");

      this.enableClickOptions.forEach((op) => {
        this.chart.on("click", op, (e) => {
          const fnName = op.replace(".", "");
          if (this[`handle${fnName}Click`]) {
            this[`handle${fnName}Click`](e);
          }
          const eventName = op.replace(".", "-");
          this.$emit(`${eventName}-click`, e);
        });
      });

      if (this.enableClickOptions.includes("seriesZoneSameWidthxAxis")) {
        // echart全图点击事件
        this.chart.getZr().on("click", (param) => {
          // 获取 点击的 触发点像素坐标
          const pointInPixel = [param.offsetX, param.offsetY];
          // 判断给定的点是否在指定的坐标系或者系列上
          if (this.chart.containPixel("grid", pointInPixel)) {
            // 获取到点击的 x轴 下标  转换为逻辑坐标
            const xIndex = this.chart.convertFromPixel(
              { seriesIndex: 0 },
              pointInPixel
            )[0];
            const _xIndex = Math.abs(xIndex);
            this.handlexAxiscategoryClick({
              value: this.chartOption.xAxis.data[_xIndex].value,
            });
          }
        });

        // echart全图移入鼠标事件
        this.chart.getZr().on("mousemove", (params) => {
          const pointInPixel = [params.offsetX, params.offsetY];
          if (this.chart.containPixel("grid", pointInPixel)) {
            // 将此区域的 鼠标样式变为 小手
            this.chart.getZr().setCursorStyle("pointer");
          }
        });
      }
    },
    setOptions() {
      let chartOption = {
        color: [
          "#5470c6",
          "#91cc75",
          "#fac858",
          "#ee6666",
          "#73c0de",
          "#3ba272",
          "#fc8452",
          "#9a60b4",
          "#ea7ccc",
        ],
        ...this.chartOption,
      };

      // 默认滚动条滚动到显示位置 -- start
      if (this.defaultZoomPosition && chartOption.dataZoom) {
        const axisName = Object.keys(this.defaultZoomPosition).find(
          (ele) => ele == "xAxis" || ele == "yAxis"
        );
        let axisValue = this.defaultZoomPosition[axisName];

        // 第一项是非空数据
        if (axisValue == "notEmpty") {
          // 找出第一组有数据的位置
          const len = chartOption[axisName].data.length;
          const index = this.getFirstDataIndex(
            chartOption,
            len,
            this.defaultZoomPosition.seriesName
          );
          if (index != null) {
            // 修改dataZoom配置，令滚动条初始化到对应位置，有数据的点显示第一
            chartOption.dataZoom.forEach((ele) => {
              const pageSize = ele.endValue - ele.startValue; //每页显示数量-1

              if (index > len - 1 - pageSize) {
                ele.startValue = len - 1 - pageSize;
                ele.endValue = len - 1;
              } else {
                ele.startValue = index;
                ele.endValue = index + pageSize;
              }
            });
          }
        } else {
          let currentValue = axisValue;

          // 最后一项是当月
          if (axisValue == "currentMonth") {
            currentValue = this.parseTime(new Date(), "{y}-{m}");
          }

          // 找出显示位置index
          const index = chartOption[axisName].data.findIndex((ele) => {
            if (typeof ele == "string") {
              return ele == currentValue;
            }
            return ele.value == currentValue;
          });

          // 修改dataZoom配置，令滚动条初始化到对应位置
          chartOption.dataZoom.forEach((ele) => {
            const pageSize = ele.endValue - ele.startValue; //每页显示数量-1

            if (index <= pageSize) {
              ele.startValue = 0;
              ele.endValue = pageSize;
            } else {
              ele.startValue = index - pageSize;
              ele.endValue = index;
            }
          });
        }
      }
      // 默认滚动条滚动到显示位置 -- end

      this.chart.setOption(chartOption);

      this.loading = false;
    },
    handlexAxiscategoryClick(e) {
      if (!this.xAxisSelectable) {
        return;
      }
      const index = this.chartOption.xAxis.data.findIndex(
        (ele) => ele.value == e.value
      );

      if (index != this.xAxisLabelActives) {
        this.updatexAxisLabelActives(index);
      }
    },
    updatexAxisLabelActives(index) {
      this.xAxisLabelActives = index;

      const _chartOption = this.deepCopyData(this.chartOption);
      delete _chartOption.dataZoom;
      this.chartOption = _chartOption;

      _chartOption.xAxis.data.forEach((ele, i) => {
        if (this.xAxisLabelActives === i) {
          // 设置选中状态
          ele.textStyle = {
            color: "#fff000",
            fontWeight: 600,
          };
        } else {
          // 取消选中状态
          ele.textStyle = {};
        }
      });

      this.setOptions();

      this.$emit("active-xAxisLabel-change", this.xAxisLabelActives);
    },
  },
  watch: {
    option: {
      deep: true,
      immediate: true,
      handler(val, oldVal) {
        if (!val) {
          return;
        }

        if (!oldVal || !this.chart) {
          this.chartOption = this.deepCopyData(val);
        } else {
          const _chartOption = this.deepCopyData(val);
          if (_chartOption.dataZoom) {
            delete _chartOption.dataZoom;
          }
          this.chartOption = _chartOption;
        }
        this.initChart();
      },
    },
  },
};
</script>
